//
// Unihan Input Method
//
// Copyright © 2002-2007 Sun Wah Linux Ltd.
//
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
// USA
//
// $Id: shuangpin.c 757 2007-05-10 08:19:31Z roger $
//

#include <stdio.h>
#include <string.h>

#include "shuangpin.h"
#include "table.h"
#include "cands_factory.h"

#define DEBUG_SP 0

static void sp_append_InputCell(UnihanIM *uim, char *cell);
static void sp_throw_a_InputCell(UnihanIM *uim);
static char *sp_get_last_InputCell(UnihanIM *uim);

//static SPFlag sp_flag = SHENGMU;

/* FS : First or Second yunmu */
/* SM_ZERO when return 1      */
int
sp_proc(UnihanIM *uim, IMKeyEvent *kev, SPTable *sp_table)
{
	int i;
	TableDataPerDesktop *dd;
	TableDataPerSession *ds;
#if DEBUG_SP
	FILE *pf;
#endif

	dd = (TableDataPerDesktop *)uim->desktopUserData;
	ds = (TableDataPerSession *)uim->sessionUserData;

	for (i=0; i<SP_TABLE_MAX_LEN; i++) {
		if (kev->keyChar == sp_table[0][i].keyname) {
			if (ds->sp_flag == SHENGMU) {
				int len = sp_strlen(sp_table[0][i].sheng, SHENGMU);
				if (len == 0) {
					uim->m->beep(uim);
					return 0;
				}
				if (sp_table[0][i].sheng[0] != SM_ZERO) {
					ds->preeditLen += len;
					strncat(ds->preedit, sp_table[0][i].sheng, len);
				}
				sp_append_InputCell(uim, sp_table[0][i].sheng);
				find_candidates(uim);
				ds->sp_flag = YUNMU;
				break;
			}
			else { //sp_flag == YUNMU
				int len = sp_strlen(sp_table[0][i].yun1, YUNMU);
				if (len) {
					ds->preeditLen += len;
					strncat(ds->preedit, sp_table[0][i].yun1, len);
					find_candidates(uim);
					sp_append_InputCell(uim, sp_table[0][i].yun1);
				}
#if DEBUG_SP
				pf = fopen("/root/debug.input", "a");
				fprintf(pf, "shuangpin traying ... \n");
				fclose(pf);
#endif
				if (!len || !ds->numCands) {
					if (len) {
						ds->preeditLen -= len;
						ds->preedit[ds->preeditLen] = 0;
						sp_throw_a_InputCell(uim);
					}
					len = sp_strlen(sp_table[0][i].yun2, YUNMU);
					if (!len) {
						uim->m->beep(uim);
						return 0;
					}
					ds->preeditLen += len;
					strncat(ds->preedit, sp_table[0][i].yun2, len);
					find_candidates(uim);
					sp_append_InputCell(uim, sp_table[0][i].yun2);
				}
				ds->sp_flag = SHENGMU;
				break;
			}
		}
	}
	return 0;
}

/* caculate length <= 4 */
int 
sp_strlen (char *str, SPFlag sp_flag)
{
	int len = strlen(str);

	if (sp_flag == SHENGMU) {
		if (len < 2)
			return len;
		else
			return 2;
	}

	if (len < 4)
		return len;
	else
		return 4;
}

void
sp_table_init(SPTable *sp_table)
{
        int i;
                                                                                                                             
        memset(sp_table, 0, sizeof(SPTable));
                                                                                                                             
        for(i=0; i<SP_TABLE_MAX_LEN-1; i++)
                sp_table[0][i].keyname = 0x61 + i;
	sp_table[0][SP_TABLE_MAX_LEN - 1].keyname = ';';
                                                                                                                             
        sp_table[0][0].sheng[0] = 0;
        sp_table[0][0].yun1[0] = 'a';
	sp_table[0][0].yun1[1] = 0;
        sp_table[0][0].yun2[0] = 0;
                                                                                                                             
        sp_table[0][1].sheng[0] = 'b';
        sp_table[0][1].sheng[1] = 0;
        sp_table[0][1].yun1[0] = 'o';
        sp_table[0][1].yun1[1] = 'u';
        sp_table[0][1].yun1[2] = 0;
        sp_table[0][1].yun2[0] = 0;
                                                                                                                             
        sp_table[0][2].sheng[0] = 'c';
        sp_table[0][2].sheng[1] = 0;
        sp_table[0][2].yun1[0] = 'i';
        sp_table[0][2].yun1[1] = 'a';
        sp_table[0][2].yun1[2] = 'o';
        sp_table[0][2].yun1[3] = 0;
        sp_table[0][2].yun2[0] = 0;

        sp_table[0][3].sheng[0] = 'd';
        sp_table[0][3].sheng[1] = 0;
        sp_table[0][3].yun1[0] = 'u';
        sp_table[0][3].yun1[1] = 'a';
        sp_table[0][3].yun1[2] = 'n';
        sp_table[0][3].yun1[3] = 'g';
        sp_table[0][3].yun2[0] = 'i';
        sp_table[0][3].yun2[1] = 'a';
        sp_table[0][3].yun2[2] = 'n';
        sp_table[0][3].yun2[3] = 'g';
 
        sp_table[0][4].sheng[0] = 0;
        sp_table[0][4].sheng[1] = 0;
        sp_table[0][4].yun1[0] = 'e';
	sp_table[0][4].yun1[1] = 0;
        sp_table[0][4].yun2[0] = 0;
 
        sp_table[0][5].sheng[0] = 'f';
        sp_table[0][5].sheng[1] = 0;
        sp_table[0][5].yun1[0] = 'e';
        sp_table[0][5].yun1[1] = 'n';
        sp_table[0][5].yun1[2] = 0;
        sp_table[0][5].yun2[0] = 0;
 
        sp_table[0][6].sheng[0] = 'g';
        sp_table[0][6].sheng[1] = 0;
        sp_table[0][6].yun1[0] = 'e';
        sp_table[0][6].yun1[1] = 'n';
        sp_table[0][6].yun1[2] = 'g';
        sp_table[0][6].yun1[3] = 0;
        sp_table[0][6].yun2[0] = 0;

        sp_table[0][7].sheng[0] = 'h';
        sp_table[0][7].sheng[1] = 0;
        sp_table[0][7].yun1[0] = 'a';
        sp_table[0][7].yun1[1] = 'n';
        sp_table[0][7].yun1[2] = 'g';
        sp_table[0][7].yun1[3] = 0;
        sp_table[0][7].yun2[0] = 0;
 
        sp_table[0][8].sheng[0] = 'c';
        sp_table[0][8].sheng[1] = 'h';
        sp_table[0][8].yun1[0] = 'i';
        sp_table[0][8].yun1[1] = 0;
        sp_table[0][8].yun2[0] = 0;
 
        sp_table[0][9].sheng[0] = 'j';
        sp_table[0][9].sheng[1] = 0;
        sp_table[0][9].yun1[0] = 'a';
        sp_table[0][9].yun1[1] = 'n';
        sp_table[0][9].yun1[2] = 0;
        sp_table[0][9].yun2[0] = 0;
 
        sp_table[0][10].sheng[0] = 'k';
        sp_table[0][10].sheng[1] = 0;
        sp_table[0][10].yun1[0] = 'a';
        sp_table[0][10].yun1[1] = 'o';
        sp_table[0][10].yun1[2] = 0;
        sp_table[0][10].yun2[0] = 0;

        sp_table[0][11].sheng[0] = 'l';
        sp_table[0][11].sheng[1] = 0;
        sp_table[0][11].yun1[0] = 'a';
        sp_table[0][11].yun1[1] = 'i';
        sp_table[0][11].yun1[2] = 0;
        sp_table[0][11].yun2[0] = 0;
 
        sp_table[0][12].sheng[0] = 'm';
        sp_table[0][12].sheng[1] = 0;
        sp_table[0][12].yun1[0] = 'i';
        sp_table[0][12].yun1[1] = 'a';
        sp_table[0][12].yun1[2] = 'n';
        sp_table[0][12].yun1[3] = 0;
        sp_table[0][12].yun2[0] = 0;
 
        sp_table[0][13].sheng[0] = 'n';
        sp_table[0][13].sheng[1] = 0;
        sp_table[0][13].yun1[0] = 'i';
        sp_table[0][13].yun1[1] = 'n';
        sp_table[0][13].yun1[2] = 0;
        sp_table[0][13].yun2[0] = 0;
 
        sp_table[0][14].sheng[0] = '.';
        sp_table[0][14].sheng[1] = 0;
        sp_table[0][14].yun1[0] = 'o';
        sp_table[0][14].yun1[1] = 0;
        sp_table[0][14].yun2[0] = 'u';
        sp_table[0][14].yun2[1] = 'o';
        sp_table[0][14].yun2[2] = 0;

        sp_table[0][15].sheng[0] = 'p';
        sp_table[0][15].sheng[1] = 0;
        sp_table[0][15].yun1[0] = 'u';
        sp_table[0][15].yun1[1] = 'n';
        sp_table[0][15].yun1[2] = 0;
        sp_table[0][15].yun2[0] = 0;
 
        sp_table[0][16].sheng[0] = 'q';
        sp_table[0][16].sheng[1] = 0;
        sp_table[0][16].yun1[0] = 'i';
        sp_table[0][16].yun1[1] = 'u';
        sp_table[0][16].yun1[2] = 0;
        sp_table[0][16].yun2[0] = 0;
 
        sp_table[0][17].sheng[0] = 'r';
        sp_table[0][17].sheng[1] = 0;
        sp_table[0][17].yun1[0] = 'u';
        sp_table[0][17].yun1[1] = 'a';
        sp_table[0][17].yun1[2] = 'n';
        sp_table[0][17].yun1[3] = 0;
        sp_table[0][17].yun2[0] = 'e';
        sp_table[0][17].yun2[1] = 'r';
        sp_table[0][17].yun2[2] = 0;

        sp_table[0][18].sheng[0] = 's';
        sp_table[0][18].sheng[1] = 0;
        sp_table[0][18].yun1[0] = 'o';
        sp_table[0][18].yun1[1] = 'n';
        sp_table[0][18].yun1[2] = 'g';
        sp_table[0][18].yun1[3] = 0;
        sp_table[0][18].yun2[0] = 'i';
        sp_table[0][18].yun2[1] = 'o';
        sp_table[0][18].yun2[2] = 'n';
        sp_table[0][18].yun2[3] = 'g';
 
        sp_table[0][19].sheng[0] = 't';
        sp_table[0][19].sheng[1] = 0;
        sp_table[0][19].yun1[0] = 'u';
        sp_table[0][19].yun1[1] = 'e';
        sp_table[0][19].yun1[2] = 0;
        sp_table[0][19].yun2[0] = 0;
 
        sp_table[0][20].sheng[0] = 's';
        sp_table[0][20].sheng[1] = 'h';
        sp_table[0][20].yun1[0] = 'u';
        sp_table[0][20].yun1[1] = 0;
        sp_table[0][20].yun2[0] = 0;
 
        sp_table[0][21].sheng[0] = 'z';
        sp_table[0][21].sheng[1] = 'h';
        sp_table[0][21].yun1[0] = 'u';
        sp_table[0][21].yun1[1] = 'i';
        sp_table[0][21].yun1[2] = 0;
        sp_table[0][21].yun2[0] = 'u';
        sp_table[0][21].yun2[1] = 'e';
        sp_table[0][21].yun2[2] = 0;

        sp_table[0][22].sheng[0] = 'w';
        sp_table[0][22].sheng[1] = 0;
        sp_table[0][22].yun1[0] = 'i';
        sp_table[0][22].yun1[1] = 'a';
        sp_table[0][22].yun1[2] = 0;
        sp_table[0][22].yun2[0] = 'u';
        sp_table[0][22].yun2[1] = 'a';
        sp_table[0][22].yun2[2] = 0;
 
        sp_table[0][23].sheng[0] = 'x';
        sp_table[0][23].sheng[1] = 0;
        sp_table[0][23].yun1[0] = 'i';
        sp_table[0][23].yun1[1] = 'e';
        sp_table[0][23].yun1[2] = 0;
        sp_table[0][23].yun2[0] = 0;
 
        sp_table[0][24].sheng[0] = 'y';
        sp_table[0][24].sheng[1] = 0;
        sp_table[0][24].yun1[0] = 'u';
        sp_table[0][24].yun1[1] = 'a';
        sp_table[0][24].yun1[2] = 'i';
        sp_table[0][24].yun1[3] = 0;
        sp_table[0][24].yun2[0] = 'v';
        sp_table[0][24].yun2[1] = 0;
                                                                                                                             
        sp_table[0][25].sheng[0] = 'z';
        sp_table[0][25].sheng[1] = 0;
        sp_table[0][25].yun1[0] = 'e';
        sp_table[0][25].yun1[0] = 'i';
        sp_table[0][25].yun1[0] = 0;
        sp_table[0][25].yun2[0] = 0;

	sp_table[0][26].sheng[0] = 0;
	sp_table[0][26].yun1[0] = 'i';
	sp_table[0][26].yun1[1] = 'n';
	sp_table[0][26].yun1[2] = 'g';
	sp_table[0][26].yun1[3] = 0;
	sp_table[0][26].yun2[0] = 0;
}

void
sp_back_space(UnihanIM *uim)
{
	TableDataPerSession *ds = (TableDataPerSession *)uim->sessionUserData;
	int len = 0;
	char *endChar = NULL;
#if DEBUG_SP
	FILE *pf;
#endif

	endChar = sp_get_last_InputCell(uim);
	if (endChar)
		len = strlen(endChar);

	if (endChar[0] != SM_ZERO) {
		ds->preeditLen -= len;
		ds->preedit[ds->preeditLen] = 0;
	}

	sp_throw_a_InputCell(uim);

	ds->sp_flag = (ds->sp_flag == YUNMU)?SHENGMU:YUNMU;
}

static void
sp_append_InputCell(UnihanIM *uim, char *cell)
{
	TableDataPerSession *ds = (TableDataPerSession *)uim->sessionUserData;

	CF_append_InputCell(&(ds->ic), cell);
}

static void
sp_throw_a_InputCell(UnihanIM *uim)
{
	TableDataPerSession *ds = (TableDataPerSession *)uim->sessionUserData;
	InputCell *endCell = ds->ic;
	InputCell *cell = ds->ic;

	if (!cell)
		return;
	if (!cell->next) {
		free(cell);
		cell = ds->ic = NULL;
		return;
	}
	while (cell->next)
		cell = cell->next;
	while (endCell->next != cell)
		endCell = endCell->next;
	free(cell);
	cell = NULL;
	endCell->next = NULL;
}

void
sp_clear_InputCell(UnihanIM *uim)
{
	TableDataPerSession *ds = (TableDataPerSession *)uim->sessionUserData;
	InputCell *cell1;
	InputCell *cell2;

	if(!ds->ic)
		return;
	cell1 = ds->ic;
	cell2 = cell1->next;
	while (cell1) {
		free(cell1);
		cell1 = cell2;
		if (cell2)
			cell2 = cell2->next;
	}
	ds->ic = NULL;
}

static char *
sp_get_last_InputCell(UnihanIM *uim)
{
	TableDataPerSession *ds = (TableDataPerSession *)uim->sessionUserData;
	InputCell *endCell;
	char *pc;

	if (!ds->ic)
		return NULL;
	endCell = ds->ic;
	while (endCell->next)
		endCell = endCell->next;
	pc = strdup(endCell->cell);
	return pc;
}

// vi:ts=4:nowrap:cin:expandtab
